package club.adger.business.controller;

import club.adger.server.dto.ResponseDto;
import club.adger.server.exception.ValidatorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: Adger
 * @Date: 2020/07/26/13:23
 * 这是一个增强的 Controller
 * 全局异常处理
 * 全局数据绑定
 * 全局数据预处理
 * 在控制层 处理 全局异常
 * 在接口中只要 抛出自定义的异常就会被这个类拦截到
 * 我们的接口防止被探测，或者只跟特定的第三方应用做对接，这时为了内部安全，不应该把参数的校验规则暴露出去，所以需要模糊返回信息
 * 类似登录接口应该返回"用户名或者密码错误"，而不是返回单个 用户名错误 或者 密码错误 这样类似的信息，会被不法分子利用信息探测
 * 原先是responseDto.setMessage(e.getMessage()); 现在是模糊信息 responseDto.setMessage("请求参数异常");
 * 不法分子 也不知道 我们是什么参数异常 但是自己可以打印日志出来 前端虽然有 但是后端不是
 */
@ControllerAdvice
public class ControllerExceptionHandler {
    private static final Logger LOG = LoggerFactory.getLogger(ControllerExceptionHandler.class);
    /**
     * 把ResponseDto以json流的方式返回回去
     *   @ExceptionHandler 一次声明，全接口生效。
     * Exception的匹配 符合" 就近原则 "
     * @param e
     * @return
     */
    @ExceptionHandler(value = ValidatorException.class)
    @ResponseBody
    public ResponseDto validatorExceptionHandler(ValidatorException e){
        ResponseDto responseDto = new ResponseDto();
        //设置类型
        responseDto.setSuccess(false);
        LOG.warn(e.getMessage());
        responseDto.setMessage("请求参数异常");
        return responseDto;
    }
}
